using Aurora.TaskScheduler.Abstractions.Message;
using Aurora.TaskScheduler.Extension.BaseJobs;
using Quartz;
using Quartz.Impl.Matchers;
using Quartz.Impl.Triggers;

namespace Aurora.TaskScheduler.Extension.Extensions;

internal static class JobExtension
{
    /// <summary>
    /// 创建 job detail
    /// </summary>
    /// <param name="task"></param>
    /// <returns></returns>
    public static IJobDetail CreateJobDetail(AppTask task)
    {
        if (task.TaskType == 1)
        {
            return JobBuilder.Create<ClassLibraryJob>()
                .WithIdentity(task.TaskName, task.GroupName)
                .Build();
        }

        return JobBuilder.Create<HttpResultJob>()
            .WithIdentity(task.TaskName, task.GroupName)
            .Build();
    }

    public static ITrigger CreateTrigger(AppTask task, bool isStartRun = true)
    {
        var triggerBuilder = TriggerBuilder.Create()
            .WithIdentity(task.TaskName, task.GroupName)
            .WithDescription(task.Describe);

        if (task.TaskExecuteType.Equals("ONE"))
        {
            triggerBuilder.StartAt(DateTimeOffset.Parse(task.Interval));
            return triggerBuilder.Build();
        }

        if (isStartRun)
        {
            triggerBuilder.StartNow();
        }

        triggerBuilder.WithCronSchedule(task.Interval);
        return triggerBuilder.Build();
    }


    public static ITrigger FindTrigger(IReadOnlyCollection<ITrigger> triggers, string taskName)
    {
        if (triggers.Count <= 0) return null;
        ITrigger trigger = triggers.Where(x => x?.JobKey.Name == taskName)?.FirstOrDefault();
        return trigger;
    }

    public static async Task<ITrigger> FindTrigger(IScheduler scheduler, JobKey jobKey)
    {
        var triggers = await scheduler.GetTriggersOfJob(jobKey);
        return FindTrigger(triggers, jobKey.Name);
    }


    public static async Task<ITrigger> FindTrigger(IScheduler scheduler, string groupName, string taskName)
    {
        JobKey jobKey = await FindJobKey(scheduler, groupName, taskName);
        ITrigger trigger = await FindTrigger(scheduler, jobKey);
        return trigger;
    }


    public static async Task<bool> Container(IScheduler scheduler, JobKey jobKey)
    {
        var container = (await scheduler.GetTriggersOfJob(jobKey))
            .Any(x => x.JobKey.Name == jobKey.Name);
        return container;
    }


    /// <summary>
    /// 根据group 获取 keys
    /// </summary>
    /// <param name="scheduler"></param>
    /// <param name="groupName"></param>
    /// <returns></returns>
    public static async Task<List<JobKey>> GetKeys(IScheduler scheduler, string groupName)
    {
        return (await scheduler.GetJobKeys(GroupMatcher<JobKey>.GroupEquals(groupName))).ToList();
    }

    /// <summary>
    /// 根据group 获取 keys
    /// </summary>
    /// <param name="scheduler"></param>
    /// <param name="groupName"></param>
    /// <param name="taskName"></param>
    /// <returns></returns>
    public static async Task<JobKey> FindJobKey(IScheduler scheduler, string groupName, string taskName)
    {
        List<JobKey> jobKeys =
            (await scheduler.GetJobKeys(GroupMatcher<JobKey>.GroupEquals(groupName))).ToList();

        foreach (var key in jobKeys)
        {
            var any = (await scheduler.GetTriggersOfJob(key)).Any(x => x.JobKey.Name == taskName);
            if (any)
                return key;
        }

        return null;
    }


    /// <summary>
    /// 判断cron 的正确性
    /// </summary>
    /// <param name="cronExpression"></param>
    /// <exception cref="MyException"></exception>
    public static bool IsValidExpression(string cronExpression)
    {
        CronTriggerImpl trigger = new CronTriggerImpl();
        trigger.CronExpressionString = cronExpression;
        DateTimeOffset? date = trigger.ComputeFirstFireTimeUtc(null);
        var isCron = date != null;
        return isCron;
    }
}